function varargout = sAnalyzer(varargin)
% SANALYZER MATLAB code for sAnalyzer.fig
%      SANALYZER, by itself, creates a new SANALYZER or raises the existing
%      singleton*.
%
%      H = SANALYZER returns the handle to a new SANALYZER or the handle to
%      the existing singleton*.
%
%      SANALYZER('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in SANALYZER.M with the given input arguments.
%
%      SANALYZER('Property','Value',...) creates a new SANALYZER or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before sAnalyzer_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to sAnalyzer_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help sAnalyzer

% Last Modified by GUIDE v2.5 16-Mar-2015 10:17:29

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @sAnalyzer_OpeningFcn, ...
                   'gui_OutputFcn',  @sAnalyzer_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before sAnalyzer is made visible.
function sAnalyzer_OpeningFcn(hObject, eventdata, handles, varargin)
 setupSAnalyzer(hObject, handles);
 handles.originalColor = [0 0 0];
 loadNonFuctionalElements(hObject, handles);
 
 loadMetabolitesReactions(hObject, handles);
 loadModel(hObject, handles);
 setupThermodinamicsDataView(hObject, handles);
 set(handles.OutputTextbox, 'String', '');
 setSAnalyzerResultsView(hObject, handles);
 loadAnalysisParameters(hObject, handles);
 WriteToOutputTextbox(handles,hObject, 'Initialization completed!')

drawnow
handles.output = hObject;
guidata(hObject, handles);

% UIWAIT makes sAnalyzer wait for user response (see UIRESUME)
% uiwait(handles.figure1);
%-------------------------------------------------------------------------

% --------------------------------------------------------------------
function setupSAnalyzer(hObject, handles)
     listCompoundsIds = init__list_of_compounds();
     maxLengthList = {'1','2','3','4','5','6','7','8','9','10'};

     if evalin('base','exist(''defines'',''var'')')
         defines = evalin('base','defines');
     else
        defines = load_defined_parametrs();
        assignin('base', 'defines', defines);
     end

     ckbxVal = 0;
     if str2num(defines.isThermodinamicUsed) & evalin('base','exist(''thermodinamicsValues'',''var'')')
        ckbxVal = 1;
     end

     handles.sortArray = splitStringToCells(defines.analysisSortArray);
     analysisCoeficients = splitStringToCells(defines.analysisCoeficients);

     set(handles.substrateConnectionMetabolites, 'String', defines.substrateConnectionMetabolites);
     set(handles.productConnectionMetabolites, 'String', defines.productConnectionMetabolites);

     set(handles.substrateMetsList,'String',listCompoundsIds);
     set(handles.productMetsList,'String',listCompoundsIds);
     set(handles.productMaxLengthList,'String',maxLengthList);
     set(handles.substrateMaxLengthList,'String',maxLengthList);

     set(handles.chbIsSubstrateUsed,'Value', str2num(defines.isSubstrateUsed));
     set(handles.chbIsProductUsed,'Value', str2num(defines.isProductUsed));
     set(handles.minBiomassFlux,'String',str2num(defines.minBiomassFluxProportion));
     set(handles.numberOfBestPathways,'String', str2num(defines.numberOfBestPathwaysReturned));
     set(handles.chbThermodinamicsUsed,'Value', ckbxVal);
     set(handles.thermodinamicsValueTreshold,'String', str2num(defines.thermodinamicTreshold));
     set(handles.productMaxLengthList,'Value',str2num(defines.maxProductPathwayLength));
     set(handles.substrateMaxLengthList,'Value',str2num(defines.maxSubstratePathwayLength));
     set(handles.chkUseSubstrateConnectionMetabolites,'Value', str2num(defines.useSubstrateConnectionMetabolites));
     set(handles.chkUseProductConnectionMetabolites,'Value', str2num(defines.useProductConnectionMetabolites));

     set(handles.combinedParam1, 'String', analysisCoeficients{1});
     set(handles.combinedParam2, 'String', analysisCoeficients{2});
     set(handles.combinedParam3, 'String', analysisCoeficients{3});
     set(handles.combinedParam4, 'String', analysisCoeficients{4});
     set(handles.combinedParam5, 'String', analysisCoeficients{5});
     set(handles.combinedParam6, 'String', analysisCoeficients{6});
     set(handles.combinedParam7, 'String', analysisCoeficients{7});

     set(handles.separateParam1, 'String', handles.sortArray{1});
     set(handles.separateParam2, 'String', handles.sortArray{2});
     set(handles.separateParam3, 'String', handles.sortArray{3});
     set(handles.separateParam4, 'String', handles.sortArray{4});
     set(handles.separateParam5, 'String', handles.sortArray{5});
     set(handles.separateParam6, 'String', handles.sortArray{6});
     set(handles.separateParam7, 'String', handles.sortArray{7});
     inx = 1;
     for i=1:length(listCompoundsIds)
         if strcmp(listCompoundsIds{i}(1:6), defines.substrateMetabolite)
            set(handles.substrateMetsList,'Value',i);
         end
         if strcmp(listCompoundsIds{i}(1:6), defines.productMetabolite)
            set(handles.productMetsList,'Value',i);
         end    
     end
     if defines.analysisOption=='1'
        set(handles.analysisOptionsSeparate,'Value',1);
     else
        set(handles.analysisOptionsCombined,'Value',1);
     end
    setReactionsOjectivesView(hObject, handles);

% --------------------------------------------------------------------
function setReactionsOjectivesView(hObject, handles)  
defines = evalin('base','defines');
reactionNameEmpty =  {'-----'};
if evalin('base','exist(''model'',''var'')')
    reactionNames = evalin('base', 'model.rxnNames');
    reactionNames = [reactionNameEmpty; reactionNames];
    set(handles.substrateObjectiveReactionList,'String',reactionNames);
    set(handles.substrateObjectiveReactionList,'Value',str2num(defines.substrateObjectiveReaction));
    set(handles.productObjectiveReactionList,'String',reactionNames);
    set(handles.productObjectiveReactionList,'Value',str2num(defines.productObjectiveReaction));
else
    set(handles.substrateObjectiveReactionList,'String',reactionNameEmpty);
    set(handles.substrateObjectiveReactionList,'Value',str2num(defines.substrateObjectiveReaction));
    set(handles.productObjectiveReactionList,'String',reactionNameEmpty);
    set(handles.productObjectiveReactionList,'Value',str2num(defines.productObjectiveReaction));
end
UpdateGui(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function substrateMetsList_Callback(hObject, eventdata, handles)
    contents = cellstr(get(hObject,'String'));
    values = regexp(contents{get(hObject,'Value')},'C.....', 'match');  
    defines = evalin('base','defines');
    defines.substrateMetabolite = values{1};
    assignin('base', 'defines', defines);
    guidata(hObject, handles);
% --------------------------------------------------------------------    

% --------------------------------------------------------------------  
function productMetsList_Callback(hObject, eventdata, handles)
    contents = cellstr(get(hObject,'String'));
    values = regexp(contents{get(hObject,'Value')},'C.....', 'match');  
    defines = evalin('base','defines');
    defines.productMetabolite = values{1};
    assignin('base', 'defines', defines);
    guidata(hObject, handles);
% --------------------------------------------------------------------  

% --------------------------------------------------------------------
function substrateMaxLengthList_Callback(hObject, eventdata, handles)
    contents = cellstr(get(hObject,'String'));
    defines = evalin('base','defines');
    defines.maxSubstratePathwayLength = contents{get(hObject,'Value')};
    assignin('base', 'defines', defines);
    guidata(hObject, handles);
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function productMaxLengthList_Callback(hObject, eventdata, handles)
    contents = cellstr(get(hObject,'String'));
    defines = evalin('base','defines');
    defines.maxProductPathwayLength = contents{get(hObject,'Value')};
    assignin('base', 'defines', defines);
    guidata(hObject, handles);
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function thermodinamicsValueTreshold_Callback(hObject, eventdata, handles)
    treshold = str2double(get(hObject,'String'))
    if isempty(treshold) | isnan(treshold)
        h = warndlg('Thermodinamics treshold contains disallowed symbols! You should correct it. Othwerwise it will be ignored and default value will be used');
    else
        defines = evalin('base','defines');
        defines.thermodinamicTreshold = num2str(treshold);
        assignin('base', 'defines', defines);
    end
    guidata(hObject, handles); 
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function numberOfBestPathways_Callback(hObject, eventdata, handles)
    treshold = str2double(get(hObject,'String'))
    if isempty(treshold) | isnan(treshold)
        h = warndlg('Number of parthways contains disallowed symbols! You should correct it. Othwerwise it will be ignored and default value will be used');
    else
        defines = evalin('base','defines');
        defines.numberOfBestPathwaysReturned = num2str(treshold);
        assignin('base', 'defines', defines);
    end
    guidata(hObject, handles); 
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function minBiomassFlux_Callback(hObject, eventdata, handles)
    minBiomass = str2double(get(hObject,'String'));
    if isempty(minBiomass) | isnan(minBiomass)
        h = warndlg('Min Biomass Input contains disallowed symbols! You should correct it. Othwerwise it will be ignored and default value will be used');
    else
        defines=evalin('base','defines');
        defines.minBiomassFluxProportion = num2str(minBiomass);
        assignin('base', 'defines', defines);
    end
    guidata(hObject, handles); 
% --------------------------------------------------------------------  
   
% --------------------------------------------------------------------
function analysisOptionsPanel_SelectionChangeFcn(hObject, eventdata, handles)
    analysisOption = 1;
    if get(handles.analysisOptionsSeparate,'Value') == 1;
        analysisOption = 1;
    else
        analysisOption = 2;
    end
    defines = evalin('base','defines');
    defines.analysisOption = num2str(analysisOption);
    assignin('base', 'defines', defines);
    guidata(hObject, handles); 
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function checkAndSaveAnalysisOptionSeparate(hObject, handles)
    value = str2double(get(hObject,'String'))
    if isempty(value) | isnan(value)
        h = warndlg('Entered value contains disallowed symbols! You should correct it. Othwerwise it will be ignored and default value will be used');
    else
        defines = evalin('base','defines');
        defines.analysisSortArray = [ ...
            get(handles.separateParam1, 'String'),  ' ' ,...
            get(handles.separateParam2, 'String'),  ' ' ,...
            get(handles.separateParam3, 'String'),  ' ' ,...
            get(handles.separateParam4, 'String'),  ' ' ,...
            get(handles.separateParam5, 'String'),  ' ' ,...
            get(handles.separateParam6, 'String'), ' ', ...
            get(handles.separateParam7, 'String')];
        assignin('base', 'defines', defines);
    end
    guidata(hObject, handles);    
% --------------------------------------------------------------------

% --------------------------------------------------------------------    
function checkAndSaveAnalysisOptionCombined(hObject, handles)
    value = str2double(get(hObject,'String'))
    if isempty(value) | isnan(value)
        h = warndlg('Entered value contains disallowed symbols! You should correct it. Othwerwise it will be ignored and default value will be used');
    else
        defines = evalin('base','defines');
        defines.analysisCoeficients = [ ...
            get(handles.combinedParam1, 'String'), ' ', ...
            get(handles.combinedParam2, 'String'), ' ', ...
            get(handles.combinedParam3, 'String'), ' ', ...
            get(handles.combinedParam4, 'String'), ' ',...
            get(handles.combinedParam5, 'String'), ' ', ...
            get(handles.combinedParam6, 'String'), ' ', ...
            get(handles.combinedParam7, 'String')];
        assignin('base', 'defines', defines);
    end
    guidata(hObject, handles); 
% --------------------------------------------------------------------

%-------------------------------------------------------------------------
function chkUseSubstrateConnectionMetabolites_Callback(hObject, eventdata, handles)
    isTrue = 'false';
    if get(hObject,'Value')
        isTrue = 'true';
    end
    defines = evalin('base','defines');
    defines.useSubstrateConnectionMetabolites = isTrue;
    assignin('base', 'defines', defines);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function chkUseProductConnectionMetabolites_Callback(hObject, eventdata, handles)
    isTrue = 'false';
    if get(hObject,'Value')
        isTrue = 'true';
    end
    defines = evalin('base','defines');
    defines.useProductConnectionMetabolites = isTrue;
    assignin('base', 'defines', defines);
%-------------------------------------------------------------------------
    
%-------------------------------------------------------------------------
function chbIsSubstrateUsed_Callback(hObject, eventdata, handles)
    isTrue = 'false';
    if get(hObject,'Value')
        isTrue = 'true';
    end
    defines = evalin('base','defines');
    defines.isSubstrateUsed = isTrue;
    assignin('base', 'defines', defines);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function chbIsProductUsed_Callback(hObject, eventdata, handles)
    isTrue = 'false';
    if get(hObject,'Value')
        isTrue = 'true';
    end
    defines = evalin('base','defines');
    defines.isProductUsed = isTrue;
    assignin('base', 'defines', defines);
%-------------------------------------------------------------------------

% --------------------------------------------------------------------
function separateParam1_Callback(hObject, eventdata, handles)
  checkAndSaveAnalysisOptionSeparate(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function separateParam2_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionSeparate(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function separateParam3_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionSeparate(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function separateParam4_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionSeparate(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function separateParam5_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionSeparate(hObject, handles);
    
function separateParam7_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionSeparate(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function combinedParam1_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionCombined(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function combinedParam2_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionCombined(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function combinedParam3_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionCombined(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function combinedParam4_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionCombined(hObject, handles);
% --------------------------------------------------------------------
% --------------------------------------------------------------------
function combinedParam5_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionCombined(hObject, handles);
% --------------------------------------------------------------------
function separateParam6_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionSeparate(hObject, handles);
    
function combinedParam6_Callback(hObject, eventdata, handles)
     checkAndSaveAnalysisOptionCombined(hObject, handles);

function combinedParam7_Callback(hObject, eventdata, handles)
    checkAndSaveAnalysisOptionCombined(hObject, handles);
    
% --------------------------------------------------------------------
function substrateConnectionMetabolites_Callback(hObject, eventdata, handles)
    defines = evalin('base','defines');
    defines.substrateConnectionMetabolites = char(get(handles.substrateConnectionMetabolites, 'String'));
    assignin('base', 'defines', defines);
    guidata(hObject, handles); 
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function productConnectionMetabolites_Callback(hObject, eventdata, handles)
    defines = evalin('base','defines');
    defines.productConnectionMetabolites = char(get(handles.productConnectionMetabolites, 'String'));
    assignin('base', 'defines', defines);
    guidata(hObject, handles); 
% --------------------------------------------------------------------




%-----------------------------------------------------------
function chbThermodinamicsUsed_Callback(hObject, eventdata, handles)
    if get(hObject,'Value')
         if ~evalin('base','exist(''thermodinamicsValues'',''var'')')
             choice = questdlg('You should load thermodinamics data to use this function','Load thermodinamics','Load','Cancel','o')
             if strcmp(choice,'Load')
                loadThermodinamicsDataFunction(hObject, handles);
             else
                set(handles.chbThermodinamicsUsed,'Value',0);
             end
         end
    end
    
    isTrue = 'false';
    if get(hObject,'Value')
        isTrue = 'true';
    end
    defines = evalin('base','defines');
    defines.isThermodinamicUsed = isTrue;
    assignin('base', 'defines', defines);
    
    setupThermodinamicsDataView(hObject, handles);
    guidata(hObject, handles);   
%----------------------------------------------------------

% --------------------------------------------------------------------
function loadThermodinamicsBtn_Callback(hObject, eventdata, handles)
    loadThermodinamicsDataFunction(hObject, handles);
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function setupThermodinamicsDataView(hObject, handles)
    isThermodinamicsUsed = get(handles.chbThermodinamicsUsed, 'Value');
    if isThermodinamicsUsed
        if evalin('base','exist(''thermodinamicsValues'',''var'')')
            set(handles.loadThermodinamicsBtn, 'String', 'Thermodinamics data loaded')
            set(handles.loadThermodinamicsBtn,'ForegroundColor', handles.originalColor);
        else
            set(handles.loadThermodinamicsBtn, 'String', 'Thermodinamics data is not loaded')
            set(handles.loadThermodinamicsBtn,'ForegroundColor', 'r');
        end
    else
       set(handles.loadThermodinamicsBtn, 'String', 'Load thermodinamics data')
       set(handles.loadThermodinamicsBtn,'ForegroundColor', handles.originalColor);
    end
% --------------------------------------------------------------------                    
            
%-------------------------------------------------------------------------
function handles = loadThermodinamicsDataFunction(hObject, handles)
   set(handles.loadThermodinamicsBtn, 'String', 'Loading ...')
   [FileName,PathName,FilterIndex] = uigetfile({'*.csv;*.xls;*.xlsx','Excel Files (*.csv,*.xls,*.xlsx)'}, ...
                                                'Open eQuilibrator Data file');
   filePath = strcat(PathName,FileName);
   if ~isempty(filePath) 
        WriteToOutputTextbox(handles,hObject, 'Loading! This can take a while ... ' );
        
        
        [ndata, text, alldata] = xlsread(filePath);
        thermodinamicsValues=[];
        h = waitbar(0,'Please wait... Looking for Reactions thermodinamics data');
        for i=2:length(text)
            waitbar(i/length(text),h, [num2str(i), ' reactions of ', num2str(length(text)), ' total' ])
            rowValue = regexp(text(i),',','split');
            reactionid='R00000';
            reactionid(6-length(rowValue{1}{1}(:,:))+1:6)=rowValue{1}{1};
            thermodinamicsValues=[thermodinamicsValues; reactionid, rowValue{1}(2)];
        end   
        close(h)
      
        if ~isempty(thermodinamicsValues)            
            assignin('base', 'thermodinamicsValues', thermodinamicsValues);
            WriteToOutputTextbox(handles,hObject, 'Thermodinamics data is loaded!' )
            clear thermodinamicsValues;
        else
             WriteToOutputTextbox(handles,hObject,'Thermodinamics data is not loaded!' )
             set(handles.chbThermodinamicsUsed,'Value',0);
        end
   else
       set(handles.chbThermodinamicsUsed,'Value',0);
   end
   setupThermodinamicsDataView(hObject, handles);
   UpdateGui(hObject,handles)
%-------------------------------------------------------------------------


%-------------------------------------------------------------------------
function loadMetabolitesReactions(hObject, handles)
    isReactionsDataLoaded = false;
    isMetabolitesDataLoaded = false;
    if evalin('base','exist(''compounds'',''var'')')
        metabolitesCount = evalin('base','length(compounds)');
        WriteToOutputTextbox(handles,hObject, ...
            ['Metabolites data is loaded! Metabolites count: ' num2str(metabolitesCount)] )
        isMetabolitesDataLoaded = true;
    else
        WriteToOutputTextbox(handles,hObject, ...
            ['Metabolites data is not loaded! It does not contains metabolites variable'])
        set(handles.loadedMetabolitesCount,'string','No data');
    end

    if evalin('base','exist(''reactions'',''var'')')
        reactionsCount = evalin('base','length(reactions)');
        WriteToOutputTextbox(handles,hObject, ...
            ['Reactions data is loaded! Reactions count: ' num2str(reactionsCount)])
        isReactionsDataLoaded = true;
    else
        set(handles.loadMetabolitesReactionsBtn,'ForegroundColor','r');
        WriteToOutputTextbox(handles,hObject, ...
        ['Reactions data is not loaded! It does not contains reactions variable'])
        set(handles.loadedReactionsCount,'string','No data');
    end
    
    updateCollectedMetabolitesReactionsInformation(hObject, handles);
    
    if ~isReactionsDataLoaded || ~isMetabolitesDataLoaded
        set(handles.loadMetabolitesReactionsBtn,'ForegroundColor','r');
    else
        set(handles.loadMetabolitesReactionsBtn,'ForegroundColor',handles.originalColor);
    end
    
UpdateGui(hObject,handles)
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function updateCollectedMetabolitesReactionsInformation(hObject, handles)
  if evalin('base','exist(''reactions'',''var'')')
    set(handles.loadedReactionsCount,'string',num2str(evalin('base','length(reactions)')));
  end
  if evalin('base','exist(''compounds'',''var'')')
    set(handles.loadedMetabolitesCount,'string',num2str(evalin('base','length(compounds)')));
  end
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function loadMetabolitesReactionsBtn_Callback(hObject, eventdata, handles)
     [FileName,PathName,FilterIndex] = ...
     uigetfile({'*.mat','Metabolites and Reactions MAT File (*.mat)'}, ...
           'Open Metabolites and Reactions Data file', '*.mat');
       
     filePath = strcat(PathName,FileName);
     if ~isempty(filePath) 
        set(handles.loadMetabolitesReactionsBtn, 'String', 'Loading ...');
        guidata(hObject, handles);
        drawnow update

        load(filePath);
        if exist('compounds','var')
            assignin('base', 'compounds', compounds);
            clear metabolites;
        end
        
        if exist('reactions','var')   
            assignin('base', 'reactions', reactions);
            clear reactions;
        end
        set(handles.loadMetabolitesReactionsBtn, 'String', 'Load metabolites and reactions');
    else
        set(handles.loadMetabolitesReactionsBtn,'ForegroundColor','r');
        WriteToOutputTextbox(handles,hObject, ...
            ['Reactions and Metabolites data does not exists']);
        set(handles.loadedReactionsCount,'String','No data');
        set(handles.loadedMetabolitesCount,'String','No data');
    end

UpdateGui(hObject,handles)

loadMetabolitesReactions(hObject, handles);
%-------------------------------------------------------------------------

% --------------------------------------------------------------------
function loadDataBtn_Callback(hObject, eventdata, handles)
    [FileName,PathName,FilterIndex] = ...
    uigetfile({'*.mat','Load sAnalyzer data MAT File (*.mat)'}, ...
           'sAnalyzer data file', '*.mat');
       
     filePath = strcat(PathName,FileName);
     if ~isempty(filePath) 
        set(handles.loadDataBtn, 'String', 'Loading ...');
        UpdateGui(hObject,handles)
        WriteToOutputTextbox(handles,hObject, 'Loading sAnalyzer data!');
        %load(filePath);
        assignin('base', 'filePath', filePath);
        evalin('base','load(filePath)');
       
        set(handles.loadDataBtn, 'String', 'Load data');
        UpdateGui(hObject,handles)
        WriteToOutputTextbox(handles,hObject, 'Data is loaded!');
     else
        WriteToOutputTextbox(handles,hObject, 'No data to load!');
     end
     loadMetabolitesReactions(hObject, handles);
     loadModel(hObject, handles);
     setReactionsOjectivesView(hObject, handles);
     setupThermodinamicsDataView(hObject, handles);
% --------------------------------------------------------------------
    
function choice = checkForExistingDataBothDirrections()
    containsMatrix = false;
    containsPathways = false;
    
    if evalin('base','exist(''prod_graphNodes'',''var'')')
        if evalin('base','exist(''prod_graphEdges'',''var'')')
            if evalin('base','exist(''prod_sMatrix'',''var'')')
                containsMatrix = true;
            end
        end
    end
    if evalin('base','exist(''prod_listOfPathways'',''var'')')
        containsPathways = true;
    end

    
    choice = 'None';
    if ~containsMatrix & ~containsPathways
        return;
    elseif (containsMatrix & containsPathways)
    choice = questdlg(...
        'Found existing sAnalyzer data. Delete existing and start new experiment or continue with existing data',...
        'Existing data found',...
        'Start new', ...
        'Start pathways analysis','o')
    end   

% --------------------------------------------------------------------
 function choice = checkForExistingData()
     
    containsMatrix = false;
    containsPathways = false;
    containsResults = false;
    
    if evalin('base','exist(''graphNodes'',''var'')')
        if evalin('base','exist(''graphEdges'',''var'')')
            if evalin('base','exist(''sMatrix'',''var'')')
                containsMatrix = true;
            end
        end
    end
    if evalin('base','exist(''listOfPathways'',''var'')')
        containsPathways = true;
    end
    if evalin('base','exist(''analyzedPathways'',''var'')')
         containsResults = true;
    end
    
    choice = 'None';
    if ~containsMatrix & ~containsPathways & ~containsResults
        return;
    elseif (containsMatrix & containsPathways & containsResults) || ...
        (containsMatrix & containsPathways & ~containsResults)
    choice = questdlg(...
        'Found existing sMatrix and pathways data. Delete existing and start new experiment or continue with existing data',...
        'Existing data found',...
        'Start new', ...
        'Start pathways search', ...
        'Start pathways analysis','o')
    elseif containsMatrix & ~containsPathways & ~containsResults
        choice = questdlg(...
        'Found existing sMatrix data. Delete existing and start new experiment or continue with existing data',...
        'Existing data found',...
        'Start new', ...
        'Start pathways search','o')
    end    
% --------------------------------------------------------------------
 
 function isBothDirrections = isBothDirrectionsTask()
     defines = evalin('base','defines');
     isBothDirrections = str2num(defines.isProductUsed) & str2num(defines.isSubstrateUsed);

% --------------------------------------------------------------------
function startAutomaticModeBtn_Callback(hObject, eventdata, handles)
    if evalin('base','exist(''defines'',''var'')')
         WriteToOutputTextbox(handles,hObject, 'Defines is loaded!' )
         defines = evalin('base','defines');
    else
         WriteToOutputTextbox(handles,hObject, 'No defines variable!' )
         choice = questdlg('You should create defines variable and configure parameters to start','Create Defines variable','Create', 'Cancel','o')
         if strcmp(choice,'Create')
              WriteToOutputTextbox(handles,hObject, 'Creating Defines variable! You should configure sAnalyzer to continue' )
              set(handles.startAutomaticModeBtn, 'String', 'Creating defines');
              setupSAnalyzer(hObject, handles);
              set(handles.startAutomaticModeBtn, 'String', 'Start sAnalyzer');
         end
         return;
    end
    if get(handles.chbThermodinamicsUsed,'Value') & ~evalin('base','exist(''thermodinamicsValues'',''var'')')
         choice = questdlg('You should load thermodinamics data or continue without it','Load thermodinamics','Load','Continue', 'Cancel','o')
         if strcmp(choice,'Load')
            loadThermodinamicsDataFunction(hObject, handles);
         elseif strcmp(choice,'Continue')
            set(handles.chbThermodinamicsUsed,'Value',0);
            defines.isThermodinamicUsed = 'false';
            return;
         end
         setupThermodinamicsDataView(hObject, handles);
    end
    if  ~evalin('base','exist(''model'',''var'')')
        WriteToOutputTextbox(handles,hObject, 'Model is not loaded! You should load model first to continue' )
        return;
    end
    
    UpdateGui(hObject, handles);
    
    if str2num(defines.isSubstrateUsed) & ~str2num(defines.isProductUsed)
        defines.initialCompound = defines.substrateMetabolite;
        defines.isSubstrateDirection = 'true';
        defines.lengthOfBuildPathways = defines.maxSubstratePathwayLength;
    elseif str2num(defines.isProductUsed) & ~str2num(defines.isSubstrateUsed)
        defines.initialCompound = defines.productMetabolite;
        defines.isSubstrateDirection = 'false';
        defines.lengthOfBuildPathways = defines.maxProductPathwayLength;
    elseif str2num(defines.isProductUsed) & str2num(defines.isSubstrateUsed)
        defines.initialCompound = defines.substrateMetabolite;
        defines.isSubstrateDirection = 'true';
        defines.lengthOfBuildPathways = defines.maxSubstratePathwayLength;
        WriteToOutputTextbox(handles,hObject, 'START BOTH DIRRECTIONS ANALYSIS' ) 
    else
         WriteToOutputTextbox(handles,hObject, 'No parameters are choosen! Please select product or/and substrate' )
         waitfor(msgbox('No parameters are choosen! Please select product or/and substrate'));
         return;
    end
    assignin('base', 'defines', defines);
  
    if str2num(defines.isSubstrateUsed) & str2num(defines.useSubstrateConnectionMetabolites)
        if length(get(handles.substrateConnectionMetabolites, 'String')) < 6
            waitfor(msgbox('Substrate connection metabolites list is empty. Please unselect use metabolites checkbox or fill list of metabolites'));
            return;
        end
    end
    if str2num(defines.isProductUsed) & str2num(defines.useProductConnectionMetabolites)
        if length(get(handles.productConnectionMetabolites, 'String')) < 6
            waitfor(msgbox('Product connection metabolites list is empty. Please unselect use metabolites checkbox or fill list of metabolites'));
            return;
        end
    end
    
    
    modelIsUsed = checkConnectionMetabolitesOrModelIsUsed();
    if ~strcmp(modelIsUsed, 'connectionMetabolites') && ~strcmp(modelIsUsed, 'model')
        msgbox('Execution is cancelled. You can currate the model and continue search of pathways manually.','Execution is cancelled')
        return;
    end
    
    
    
    if ~isBothDirrectionsTask()
        choice = checkForExistingData();
        if isempty(choice)
             WriteToOutputTextbox(handles,hObject, 'Nothing selected. Canceling ...' )
            return;
        end

        
        set(handles.startAutomaticModeBtn, 'String', 'Working');
        UpdateGui(hObject, handles);

        if isequal(choice, 'None') || isequal(choice, 'Start new')
            WriteToOutputTextbox(handles,hObject, 'Starting automatic sAnalyzer mode!' )

            if evalin('base','exist(''listOfPathways'',''var'')')
            evalin('base',['clear ','listOfPathways']);
            end
            if evalin('base','exist(''arrayOfAllPathwaysWeights'',''var'')')
            evalin('base',['clear ','arrayOfAllPathwaysWeights']);
             evalin('base',['clear ','analyzedPathways']);
            end
            if evalin('base','exist(''sMatrix'',''var'')')
            evalin('base',['clear ','sMatrix']);
            end
            if evalin('base','exist(''graphEdges'',''var'')')
            evalin('base',['clear ','graphEdges']);
            evalin('base',['clear ','graphNodes']);
            end
            setSAnalyzerResultsView(hObject, handles);
        
            startGraphConstruction(hObject, handles);
            startPathwaysSearch(hObject, handles);
            startPathwaysAnalysis(hObject, handles);
        elseif isequal(choice,'Start pathways search')
          
            if evalin('base','exist(''arrayOfAllPathwaysWeights'',''var'')')
            evalin('base',['clear ','arrayOfAllPathwaysWeights']);
            evalin('base',['clear ','analyzedPathways']);
            end
            if evalin('base','exist(''listOfPathways'',''var'')')
            evalin('base',['clear ','listOfPathways']);
            end
            
            setSAnalyzerResultsView(hObject, handles);
            
            startPathwaysSearch(hObject, handles);
            startPathwaysAnalysis(hObject, handles);
        elseif isequal(choice,'Start pathways analysis')
           
            if evalin('base','exist(''arrayOfAllPathwaysWeights'',''var'')')
            evalin('base',['clear ','arrayOfAllPathwaysWeights']);
            evalin('base',['clear ','analyzedPathways']);
            end
            setSAnalyzerResultsView(hObject, handles);
            startPathwaysAnalysis(hObject, handles);
        end
    else
        choice = checkForExistingDataBothDirrections();
        if isempty(choice)
             WriteToOutputTextbox(handles,hObject, 'Nothing selected. Canceling ...' )
            return;
        end
        

         if isequal(choice, 'None') || isequal(choice, 'Start new')
            if evalin('base','exist(''prod_listOfPathways'',''var'')')
                evalin('base',['clear ','prod_listOfPathways']);
            end
            if evalin('base','exist(''prod_sMatrix'',''var'')')
                evalin('base',['clear ','prod_sMatrix']);
            end
            if evalin('base','exist(''prod_graphEdges'',''var'')')
                evalin('base',['clear ','prod_graphEdges']);
                evalin('base',['clear ','prod_graphNodes']);
            end
            if evalin('base','exist(''listOfPathways'',''var'')')
                evalin('base',['clear ','listOfPathways']);
            end
            if evalin('base','exist(''arrayOfAllPathwaysWeights'',''var'')')
                evalin('base',['clear ','arrayOfAllPathwaysWeights']);
                evalin('base',['clear ','analyzedPathways']);
            end
            if evalin('base','exist(''sMatrix'',''var'')')
                evalin('base',['clear ','sMatrix']);
            end
            if evalin('base','exist(''graphEdges'',''var'')')
                evalin('base',['clear ','graphEdges']);
                evalin('base',['clear ','graphNodes']);
            end
            
            setSAnalyzerResultsView(hObject, handles);
            set(handles.startAutomaticModeBtn, 'String', 'Working');
            UpdateGui(hObject, handles);

            evalin('base','originalObjectiveReaction=find(model.c,1);')

            startGraphConstruction(hObject, handles);
            startPathwaysSearch(hObject, handles);

            if evalin('base','exist(''listOfPathways'',''var'')')
                evalin('base','prod_listOfPathways=listOfPathways;')
                evalin('base','prod_sMatrix=sMatrix;')
                evalin('base','prod_graphEdges=graphEdges;')
                evalin('base','prod_graphNodes=graphNodes;')
                evalin('base',['clear ','listOfPathways']);
                evalin('base',['clear ','sMatrix']);
                evalin('base',['clear ','graphEdges']);
                evalin('base',['clear ','graphNodes']);
            end

            defines.initialCompound = defines.productMetabolite;
            defines.isSubstrateDirection = 'false';
            defines.lengthOfBuildPathways = defines.maxProductPathwayLength;

            assignin('base', 'defines', defines);

            startGraphConstruction(hObject, handles);
            startPathwaysSearch(hObject, handles);

            analyze_pathways_both_dirrections();
            
            setSAnalyzerResultsView(hObject, handles);
         else isequal(choice, 'Start pathways analysis')
            if evalin('base','exist(''arrayOfAllPathwaysWeights'',''var'')')
                evalin('base',['clear ','arrayOfAllPathwaysWeights']);
                evalin('base',['clear ','analyzedPathways']);
            end
            setSAnalyzerResultsView(hObject, handles);
            set(handles.startAutomaticModeBtn, 'String', 'Working');
            UpdateGui(hObject, handles);
            analyze_pathways_both_dirrections();

            setSAnalyzerResultsView(hObject, handles);
         end
    end
    
    WriteToOutputTextbox(handles,hObject, 'Finished sAnalyzer mode!' )
    set(handles.startAutomaticModeBtn, 'String', 'Start sAnalyzer');
    UpdateGui(hObject, handles);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function startGraphConstruction(hObject, handles)
    WriteToOutputTextbox(handles,hObject, 'Starting graph construction!' )

    start_graph_construction('true'); %true - can be checkbox
    WriteToOutputTextbox(handles,hObject, 'Graph data is loaded!' )
    setSAnalyzerResultsView(hObject, handles);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function startPathwaysSearch(hObject, handles)
    WriteToOutputTextbox(handles,hObject, 'Starting pathways search!' )
    
if ~evalin('base',['size(graphEdges) == [0,0]'])
    get_all_pathways2();
else
     WriteToOutputTextbox(handles,hObject, 'No sMatrix Found!' )
     setSAnalyzerResultsView(hObject, handles);
end

    WriteToOutputTextbox(handles,hObject, 'Pathways data is loaded!' )
    setSAnalyzerResultsView(hObject, handles);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function startPathwaysAnalysis(hObject, handles)
    WriteToOutputTextbox(handles,hObject, 'Starting pathways analysis!') 
    
    
    if ~evalin('base',['size(graphEdges) == [0,0]'])
        analyze_pathways();
else
     WriteToOutputTextbox(handles,hObject, 'No sMatrix Found!' )
     setSAnalyzerResultsView(hObject, handles);
    end

    

    WriteToOutputTextbox(handles,hObject, 'Results data is loaded!' )
    setSAnalyzerResultsView(hObject, handles);
%-------------------------------------------------------------------------

%-------------------------------------------------------------------------
function setSAnalyzerResultsView(hObject, handles)
    if ~isBothDirrectionsTask()
        if evalin('base','exist(''graphNodes'',''var'')')
             set(handles.sMatrixSizeLabel,'string',[num2str(evalin('base','length(graphNodes)')) ...
                 ' x ' num2str(evalin('base','length(graphEdges)'))]);
        else
             set(handles.sMatrixSizeLabel,'string', 'No data');
        end

        if evalin('base','exist(''listOfPathways'',''var'')')
             set(handles.foundPathwaysCountLabel,'string',num2str(evalin('base','length(listOfPathways)')));
        else
             set(handles.foundPathwaysCountLabel,'string', 'No data');
        end

        if evalin('base','exist(''analyzedPathways'',''var'')')
             set(handles.analyzedPathaysCountLabel,'string',num2str(evalin('base','length(analyzedPathways)')));
        else
             set(handles.analyzedPathaysCountLabel,'string', 'No data');
        end
    else
        if evalin('base','exist(''graphNodes'',''var'')')
            smatrix = ['product sMatrix: ' num2str(evalin('base','length(graphNodes)')) ...
                 ' x ' num2str(evalin('base','length(graphEdges)'))];
            if evalin('base','exist(''prod_graphNodes'',''var'')')
                smatrix = [smatrix '; substrate sMatrix: ' num2str(evalin('base','length(prod_graphNodes)')) ...
                 ' x ' num2str(evalin('base','length(prod_graphEdges)'))];
            end
            set(handles.sMatrixSizeLabel,'string',smatrix);
        else
            set(handles.sMatrixSizeLabel,'string', 'No data');
        end
        
       

        if evalin('base','exist(''listOfPathways'',''var'')')
              listPathways = ['product: ' num2str(evalin('base','length(listOfPathways)'))];
              if evalin('base','exist(''prod_listOfPathways'',''var'')')
                listPathways = [listPathways '; substrate: ' num2str(evalin('base','length(prod_listOfPathways)'))];
              end
            
             set(handles.foundPathwaysCountLabel,'string',listPathways);
        
        else
             set(handles.foundPathwaysCountLabel,'string', 'No data');
        end

        if evalin('base','exist(''analyzedPathways'',''var'')')
            analyzedPathways = [' ' num2str(evalin('base','length(analyzedPathways)'))];
            set(handles.analyzedPathaysCountLabel,'string',analyzedPathways);
        else
             set(handles.analyzedPathaysCountLabel,'string', 'No data');
        end
    end
    
    UpdateGui(hObject, handles);
%-------------------------------------------------------------------------

% --------------------------------------------------------------------
function showSaveResultsBtn_Callback(hObject, eventdata, handles)
    if evalin('base','exist(''analyzedPathways'',''var'')')
       initCobraToolbox
       untitled
    else
        WriteToOutputTextbox(handles,hObject, 'No data to show!')
    end
% --------------------------------------------------------------------

%----------------------------------------------------------------------
function loadModel(hObject, handles)
    if evalin('base','exist(''model'',''var'')')
        metabolitesCount = evalin('base','length(model.metKEGGID)');
        metabolitesWOKEGGCount = metabolitesCount - evalin('base','length(model.metKEGGID(~cellfun(@isempty, model.metKEGGID)))');
        reactionsCount = evalin('base','length(model.rxns)');
       
        set(handles.modelMetabolitesCount, 'String', num2str(metabolitesCount));
        set(handles.modelMetabolitesWOKEGGCount, 'String', num2str(metabolitesWOKEGGCount));
        set(handles.modelReactionsCount, 'String', num2str(reactionsCount));
        
        WriteToOutputTextbox(handles,hObject,['Model is loaded!'])
        set(handles.loadModelBtn,'String', 'Model is loaded');
        set(handles.loadModelBtn,'ForegroundColor',handles.originalColor);
    else
        WriteToOutputTextbox(handles,hObject, ['Model is not loaded'])
        set(handles.loadModelBtn,'String', 'Model is not loaded');
        set(handles.loadModelBtn,'ForegroundColor', 'r');
        
        set(handles.modelMetabolitesCount, 'String', 'No data');
        set(handles.modelMetabolitesWOKEGGCount, 'String', 'No data');
        set(handles.modelReactionsCount, 'String', 'No data');
    end
    UpdateGui(hObject, handles);
%---------------------------------------------------------------

% --------------------------------------------------------------------
function loadModelBtn_Callback(hObject, eventdata, handles)
    [FileName,PathName,FilterIndex] = uigetfile({'*.xml', 'Model XML File (*.xml)'; ...
        '*.mat','Model MAT File (*.mat)'},'Open Model Data file');
    filePath = strcat(PathName,FileName);
    try
       if ~isempty(filePath)
           [pathstr,name,extension] = fileparts(filePath);

           set(handles.loadModelBtn,'String', 'Cobra init ...');
           UpdateGui(hObject, handles);
           WriteToOutputTextbox(handles,hObject, 'Starting Cobra initialization');

           initCobraToolbox;
           WriteToOutputTextbox(handles,hObject, 'Cobra is initialized');
           WriteToOutputTextbox(handles,hObject, 'Reading model file');

           set(handles.loadModelBtn,'String', 'Model loading ...');
           UpdateGui(hObject, handles);

           if isequal(extension,'.mat')
               load(filePath);
           else
               model = readCbModel(filePath);
           end
           if exist('model','var')
               WriteToOutputTextbox(handles,hObject, ...
                    'Model is loaded! Starting filling model with KEGG IDs' )

               set(handles.loadModelBtn,'String', 'Init Model ...');
               UpdateGui(hObject, handles);

               model = CheckMOdelToKEGGData(model);

               assignin('base', 'model', model);
               guidata(hObject, handles);
               WriteToOutputTextbox(handles,hObject, ...
                   'Model is ready!' )
               clear model;

               set(handles.loadModelBtn,'String', 'Model is loaded');
               UpdateGui(hObject, handles);
               setReactionsOjectivesView(hObject, handles) ;
           else
               WriteToOutputTextbox(handles,hObject, ...
                   ['Model is not loaded! File does not contains model'])
               set(handles.loadModelBtn,'String', 'Model is not loaded');
               UpdateGui(hObject, handles);
           end
       else
           WriteToOutputTextbox(handles,hObject, ...
                ['Model is not loaded! File is not choosen'])
           set(handles.loadModelBtn,'String', 'Model is not loaded');
           UpdateGui(hObject, handles);
       end
       loadModel(hObject, handles);
    catch err
       disp(err);
    end
    guidata(hObject, handles);
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function UpdateGui(hObject,handles)
    guidata(hObject, handles);
    drawnow update
% --------------------------------------------------------------------     
    
% --------------------------------------------------------------------    
function model = CheckMOdelToKEGGData(model)
    metKEGGID = model.metKEGGID;
    emptyKEGGID = 0;
    for i = 1:length(metKEGGID)
        if ~isempty(metKEGGID{i})
           metaboliteKEGGIDs_KEGGID(i) = cellstr(metKEGGID{i});
        else
            emptyKEGGID = emptyKEGGID + 1;
        end
    end   
    percentEmptyKEGGID = emptyKEGGID * 100 / length(metKEGGID);
    choice = questdlg(['In model are ', num2str(percentEmptyKEGGID), ...
        '% empty KEGGIDs. Do you want to try to fill model with KEGGIDs?'], ...
        'Load KEGGIDs','Fill','No','o')
    if strcmp(choice,'Fill')
        model = init_model(model);
    end
% --------------------------------------------------------------------

%----------------------------------------------------------------------
function saveReactionsAndMetabolites(handles,hObject)
    if evalin('base','exist(''reactions'',''var'')') && evalin('base','exist(''compounds'',''var'')')
       reactions = evalin('base','reactions');
       metabolites = evalin('base','compounds');
       
       [FileName,PathName,FilterIndex] = uiputfile({'MetabolitesAndReactions.mat','Meatbolites and Reactions Data MAT File (*.mat)'}, ...
                                                    'Save Data file','MetabolitesAndReactions.mat');
       filePath = strcat(PathName,FileName);
       if ~isempty(filePath) 
            save(filePath,'reactions', 'metabolites');
            WriteToOutputTextbox(handles,hObject, 'Reactions and Metabolites data is saved to harddrive! You can load it later')
       else
            WriteToOutputTextbox(handles,hObject, 'Reactions and Metabolites data is not saved! Try again!')
       end
       clear reactions
       clear metabolites
    end
% --------------------------------------------------------------------

% ----------SAVE ALL DATA----------------------------------------------------------
function saveDataBtn_Callback(hObject, eventdata, handles)
    
    %ask for saving
    choice = questdlg('Do you want to save metabolites and reactions data as separate file? ', ...
        'Save metabolites and reactions','Yes','No','o')
    if strcmp(choice,'Yes')
        saveReactionsAndMetabolites(handles, hObject);
    end
    
    [FileName,PathName,FilterIndex] = uiputfile({'sAnalyzer_data.mat','sMatrix MAT File (*.mat)'}, ...
                                                    'Save sAnalyzer Data file','sAnalyzer_data.mat');
    filePath = strcat(PathName,FileName);
    if ~isempty(filePath)
        assignin('base', 'filePath', filePath);
        evalin('base','save(filePath)')
        WriteToOutputTextbox(handles,hObject, 'sAnalyzer data is saved to harddrive! You can load it later')
    else
        WriteToOutputTextbox(handles,hObject, 'sAnalyzer data is not saved! Try again!')
    end
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function clearDataBtn_Callback(hObject, eventdata, handles)
    set(handles.clearDataBtn, 'String', 'Clearing ...')
    UpdateGui(hObject,handles)
    
    evalin('base','clear')
    
    set(handles.clearDataBtn, 'String', 'Init sAnalyzer ...')
    UpdateGui(hObject,handles)
    
    loadMetabolitesReactions(hObject, handles);
    loadModel(hObject, handles);
    setupThermodinamicsDataView(hObject, handles);
    set(handles.OutputTextbox, 'String', '');
    
    set(handles.clearDataBtn, 'String', 'Setup ...')
    UpdateGui(hObject,handles)
    
    WriteToOutputTextbox(handles,hObject, 'All data is cleared!')
    WriteToOutputTextbox(handles,hObject, 'Setting up sAnalyzer!')
    setupSAnalyzer(hObject, handles);
    
    set(handles.clearDataBtn, 'String', 'Clear data')
    UpdateGui(hObject,handles)
% --------------------------------------------------------------------

% --------------------------------------------------------------------
function editNonFunctionalElements_Callback(hObject, eventdata, handles)
    if ~isequal(get(handles.editNonFunctionalElements,'ForegroundColor'), handles.originalColor)
        clearElementsToExcludeFunction(hObject, handles);
        loadNonFuctionalElements(hObject, handles);
    else  
        waitfor(msgbox('You should to reload data afterwards'));
        open('datfiles/listOfMeabolitesToExclude.txt');
        set(handles.editNonFunctionalElements,'ForegroundColor', 'r');
        set(handles.editNonFunctionalElements,'String','Reload forbidden elements');
    end
    guidata(hObject, handles);
    drawnow update
%-------------------------------------------------------------------------   
  
% --------------------------------------------------------------------
function clearElementsToExcludeFunction(hObject, handles)
    if evalin('base','exist(''elementsToExclude'',''var'')')
        evalin('base',['clear ','elementsToExclude']);
        WriteToOutputTextbox(handles, hObject, 'Forbidden elements data is cleared!')
    end
    guidata(hObject, handles);
    drawnow update
%-------------------------------------------------------------------------
 
% --------------------------------------------------------------------
 function loadNonFuctionalElements(hObject, handles)
    WriteToOutputTextbox(handles,hObject, 'Loading forbidden elements!')
    elementsToExclude = textread('datfiles/listOfMeabolitesToExclude.txt', '%s', 'whitespace', ' ');   
    set(handles.editNonFunctionalElements,'String','Edit forbidden elements');
    set(handles.editNonFunctionalElements,'ForegroundColor', handles.originalColor);

    if ~isempty(elementsToExclude)
        assignin('base', 'elementsToExclude', elementsToExclude);
    else
        WriteToOutputTextbox(handles,hObject, 'Forbidden elements are not loaded!')
    end
    set(handles.nonFunctionalMetabolitesList,'string',elementsToExclude);
    clear elementsToExclude;
    guidata(hObject, handles);
    drawnow update
%-------------------------------------------------------------------------

% --------------------------------------------------------------------
function WriteToOutputTextbox(handles,hObject, text)
    text
    outtext = get(handles.OutputTextbox,'String');
    if ~isempty(outtext)
        [row, col] = size(outtext);
        if row > 100
           outtext(101,:) = [];
        end
    end
    outtext = {strcat('# ',text); outtext};
    set(handles.OutputTextbox, 'String', char(outtext));
guidata(hObject, handles);
drawnow update
%-------------------------------------------------------------------------


% --- Executes on button press in editAnalysisCoefiecients.
function editAnalysisCoefiecients_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function productObjectiveReactionList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in substrateObjectiveReactionList.
function substrateObjectiveReactionList_Callback(hObject, eventdata, handles)
    val = get(handles.substrateObjectiveReactionList,'Value');
    defines = evalin('base','defines');
    defines.substrateObjectiveReaction = num2str(val);
    assignin('base', 'defines', defines);
guidata(hObject, handles);

% --- Executes on selection change in productObjectiveReactionList.
function productObjectiveReactionList_Callback(hObject, eventdata, handles)
  val = get(handles.productObjectiveReactionList,'Value');
    defines = evalin('base','defines');
    defines.productObjectiveReaction = num2str(val);
    assignin('base', 'defines', defines);
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function substrateObjectiveReactionList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in editAddionalAnalysisParameters.
function editAddionalAnalysisParameters_Callback(hObject, eventdata, handles)
  if ~isequal(get(handles.editAddionalAnalysisParameters,'ForegroundColor'), handles.originalColor)
        clearAnalysisParameters(hObject, handles);
        loadAnalysisParameters(hObject, handles);
    else  
        waitfor(msgbox('You should to reload data afterwards'));
        open('datfiles/analysisParameters.txt');
        set(handles.editAddionalAnalysisParameters,'ForegroundColor', 'r');
        set(handles.editAddionalAnalysisParameters,'String','Reload analysis parameters');
    end
    UpdateGui(hObject, handles);
%-------------------------------------------------------------------------   
 
function clearAnalysisParameters(hObject, handles)
    if evalin('base','exist(''analysisParameters'',''var'')')
        evalin('base',['clear ','analysisParameters']);
        WriteToOutputTextbox(handles, hObject, 'Analysis parameters are cleared!')
    end
    UpdateGui(hObject, handles);
%-------------------------------------------------------------------------
 
% --------------------------------------------------------------------
 function loadAnalysisParameters(hObject, handles)
    WriteToOutputTextbox(handles,hObject, 'Loading analysis parameters!')
 
    parameters = load_analysis_parametrs();
    if ~isempty(parameters)
        set(handles.editAddionalAnalysisParameters,'String','Edit additional analysis coeficients');
        set(handles.editAddionalAnalysisParameters,'ForegroundColor', handles.originalColor);
        assignin('base', 'analysisParameters', parameters);
    else
        WriteToOutputTextbox(handles,hObject, 'Analysis parameters are not loaded!')
        set(handles.editAddionalAnalysisParameters,'String','Reload additional analysis coeficients');
        set(handles.editAddionalAnalysisParameters,'ForegroundColor', 'r');
    end
    clear parameters;
    UpdateGui(hObject, handles);
%-------------------------------------------------------------------------









% --- Executes during object creation, after setting all properties.
function separateParam6_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam6_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam7_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam7_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --------------------------------------------------------------------
% --- Outputs from this function are returned to the command line.
function varargout = sAnalyzer_OutputFcn(hObject, eventdata, handles) 
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in checkbox1.
function checkbox1_Callback(hObject, eventdata, handles)
% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
% --- Executes on selection change in substrateMetsList.

% --- Executes during object creation, after setting all properties.
function substrateMetsList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in popupmenu2.
function popupmenu2_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function popupmenu2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in popupmenu4.
function popupmenu4_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function popupmenu4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in popupmenu5.
function popupmenu5_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function popupmenu5_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end 
% --- Executes during object creation, after setting all properties.
function substrateMaxLengthList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in popupmenu7.
function popupmenu7_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function popupmenu7_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in checkbox3.
function checkbox3_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function productMetsList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in popupmenu9.
function popupmenu9_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function popupmenu9_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function productMaxLengthList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function substrateConnectionMetabolites_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function separateParam5_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function combinedParam5_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in nonFunctionalMetabolitesList.
function nonFunctionalMetabolitesList_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function nonFunctionalMetabolitesList_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation
function OutputTextbox_Callback(hObject, eventdata, handles)
% --- Executes during object creation, after setting all properties.
function OutputTextbox_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function thermodinamicsValueTreshold_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function numberOfBestPathways_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function minBiomassFlux_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function productConnectionMetabolites_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
% --------------------------------------------------------------------
